<template>
  <page-meta :root-font-size="rootFontSize() + 'px'"> </page-meta>

  <view class="page-container" :style="{ overflow: showPopup ? 'hidden' : 'auto' }">
    <customHeader title="发音讲解-融合现象" />
    <view class="page-content" :style="{ top: height }">

      <view class="word-detail" v-if="detailData.type == 0">
        <view class="detail-practice" :style="{ color: handleSetTextColor(detailData.score) }">
          <text class="score">{{ detailData.score }}</text>
          <text class="word">{{ detailData.practice }}</text>
        </view>
        <view class="detail-line"></view>
        <view class="detail-wrapper">
          <view class="wrapper-tag"></view>
          <view class="wrapper-header">
            <view class="wrapper-title">音素分析</view>
            <view class="wrapper-speaker">
              <loudspeaker class="speaker-loudspeaker" :voice="detailData.user_voice" />
              <text class="speaker-label">我的录音</text>
            </view>
          </view>
          <view class="wrapper-line"></view>
          <view class="wrapper-sound">
            <view class="sound-row">
              标准发音：{{ phoneme.char }}
              <text class="sound">{{ phoneme.phone_str }}</text>
            </view>
            <view class="sound-row">
              你的发音：{{ phoneme.char }}
              <rich-text class="sound" :nodes="phonemeNode"></rich-text>
            </view>
          </view>
          <view class="wrapper-line"></view>
          <view class="wrapper-label">
            <view class="label-item" v-for="item in labelList" :key="item.label">
              <view :class="['label-tag', item.label]"></view>
              <text class="label-text">{{ item.label }}</text>
            </view>
          </view>
        </view>
      </view>

      <view class="evaluate-container" v-else>
        <view class="evaluate-score">
          <view class="score-wrapper">
            <view class="score-analyze">
              <view class="score">{{ score }}</view>
              <view class="analyze" @click="handlePopUp">音素分析</view>
            </view>
            <view class="score-content" v-if="Array.isArray(evaluate.analysis.wordsDetail)">
              <wordNote v-for="(item, index) in evaluate.analysis.wordsDetail" :key="index + item.lab" :word="item" />
              <image class="tonescore-image"
                :src="evaluate.analysis.wordsDetail.slice(-1).tonescore == 1 ? tonescoreUp : tonescoreDown" />
            </view>
          </view>
          <view class="score-desc">
            <view class="desc-item mr ml">
              <view class="desc-tag awesome"></view>
              <text class="desc-label">Awesome</text>
            </view>
            <view class="desc-item mr">
              <view class="desc-tag good"></view>
              <text class="desc-label">Good</text>
            </view>
            <view class="desc-item mr">
              <view class="desc-tag average"></view>
              <text class="desc-label">Average</text>
            </view>
            <view class="desc-item mr">
              <view class="desc-tag wrong"></view>
              <text class="desc-label">Wrong</text>
            </view>
            <view class="desc-item mr ml">
              <view class="desc-stress"></view>
              <text class="desc-label">stress</text>
            </view>
            <view class="desc-item mr">
              <image class="desc-image" src="https://rwstatic.tentons.cn/web/Lesson/images/tonescore-up.png" />
              <text class="desc-label">rising intonation</text>
            </view>
            <view class="desc-item">
              <image class="desc-image" src="https://rwstatic.tentons.cn/web/Lesson/images/tonescore-down.png" />
              <text class="desc-label">falling intonation</text>
            </view>
          </view>
        </view>
        <view class="evaluate-sentence">
          <view class="evaluate-sentence-wrapper">
            <view class="sentence-title">整句分析</view>
            <view class="sentence-row">
              <view class="col-content">
                <text class="score">{{ evaluate.analysis.fluency_overall }}</text>
                <text class="desc">流利度</text>
              </view>
              <view class="col-content">
                <text class="score">{{ evaluate.analysis.integrity }}</text>
                <text class="desc">完整度</text>
              </view>
              <view class="col-content">
                <text class="score">{{ evaluate.analysis.accuracy ? evaluate.analysis.accuracy : "— —" }}</text>
                <text class="desc">准确度</text>
              </view>
            </view>

            <view class="sentence-title">朗读分析</view>
            <view class="sentence-info">
              <view class="info-list">
                <view class="list-label">录音</view>
                <loudspeaker class="list-speaker" :voice="user_voice" />
              </view>
              <view class="info-list" v-for="item in infoList" :key="item.id">
                <view class="list-label">{{ item.label }}</view>
                <view :class="['list-desc', [1, 2, 3].includes(item.id) && item.desc !== '无' ? 'error' : '']">
                  {{ item.desc }}
                </view>
              </view>
            </view>
            <view class="h12"></view>
            <image class="sentence-status"
              src="https://rwstatic.tentons.cn/web/Lesson/images/sentence-end-status.png" />
            <view class="h20"></view>
            <view class="tag"></view>
          </view>
        </view>
        <view class="evaluate-line"></view>

        <uni-popup ref="popupRef" type="bottom" :safe-area="false" :mask-click="false">
          <view class="evaluate-popup-content">
            <image class="popup-close" src="https://rwstatic.tentons.cn/web/Lesson/images/close-icon.png"
              @click="handleClosePopup" />
            <view class="popup-title">
              音素分析
              <text class="popup-title-label">点击单词切换查看音素详细解析</text>
            </view>
            <view class="popup-words">
              <view class="word" v-for="(item, index) in evaluate.analysis.wordsDetail" :key="index + item.lab"
                @click="handleActiveWord(item, index)">
                <wordNote :word="item" :show-score="false" :show-under-line="false"
                  :show-active="activeIndex === index ? true : false" />
              </view>
            </view>
            <view class="popup-sound">
              <view class="sound-row">
                标准发音：{{ standardWord.word }}
                <text class="sound">{{ standardWord.sound }}</text>
              </view>
              <view class="sound-row">
                你的发音：{{ userWord.word }}
                <rich-text class="sound" :nodes="userWord.sound"></rich-text>
              </view>
            </view>
            <view class="popup-label">
              <view class="label-item" v-for="item in labelList" :key="item.label">
                <view :class="['label-tag', item.label]"></view>
                <text class="label-text">{{ item.label }}</text>
              </view>
            </view>
            <view class="popup-line"></view>
          </view>
        </uni-popup>
      </view>
    </view>
  </view>

  <CwCommon />
</template>

<script setup lang="ts">
import { ref } from "vue";
import { rootFontSize, util } from "@/utils/util";
import { onLoad } from "@dcloudio/uni-app";
import wordNote from "@/pages/lowPricedCourse/situationalDialog/scoreResult/wordNote.vue";
import loudspeaker from "@/components/loudspeaker.vue";
import { startEvaluating } from "@/utils/chivox";
// @ts-ignore
import { ossDownLoad } from "@/utils/oss/oss.js";
import API from "@/api";

const tonescoreUp = "https://rwstatic.tentons.cn/web/Lesson/images/tonescore-up.png";
const tonescoreDown = "https://rwstatic.tentons.cn/web/Lesson/images/tonescore-down.png";

interface IEvaluate {
  [x: string]: any;
}

const fs = uni.getFileSystemManager();
const height = ref(getApp().globalData!.pageTop);

const phoneme = ref<any>({});
const phonemeNode = ref<any[]>([]);
const detailData = ref<AnyObject>({});
const labelList = ref([
  {
    label: "Awesome",
  },
  {
    label: "Good",
  },
  {
    label: "Average",
  },
  {
    label: "Wrong",
  },
]);

const popupRef = ref<any>(null);
const score = ref(0);
const user_voice = ref("");
const showPopup = ref(false);
const evaluate = ref<IEvaluate>({
  analysis: {
    wordsDetail: [],
  },
});
const activeIndex = ref(0);
const standardWord = ref({
  word: "",
  sound: "",
});
const userWord = ref({
  word: "",
  sound: [],
});
const infoList = ref([
  {
    id: 1,
    label: "多读",
    desc: "",
  },
  {
    id: 2,
    label: "漏读",
    desc: "",
  },
  {
    id: 3,
    label: "错读",
    desc: "",
  },
  {
    id: 4,
    label: "停顿次数",
    desc: "",
  },
  {
    id: 5,
    label: "录音语速",
    desc: "",
  },
]);

onLoad(async (option: any) => {
  if (option.data) {
    const result = JSON.parse(decodeURIComponent(option.data));

    if (result.type == 0) {
      detailData.value = result;
      phoneme.value = result.analysis.phoneme[0];
      handleSetPhoneme();
    } else {
      score.value = result.score;
      user_voice.value = result.user_voice;
      evaluate.value = result;
      handleSetInfoList(result.analysis);
    }
  }
})

const handleSetTextColor = (score: number) => {
  if (score >= 0 && score <= 40) {
    return "#DE4235";
  } else if (score >= 41 && score <= 59) {
    return "#FFAF00";
  } else if (score >= 60 && score <= 79) {
    return "#7EB6E6";
  } else if (score >= 80 && score <= 100) {
    return "#B0BD3B";
  }
};

const handleSetPhoneme = () => {
  let soundColor = "";
  let childrenNodes: any[] = [
    {
      name: "span",
      attrs: {
        class: "rich-text_tag",
      },
      children: [
        {
          type: "text",
          text: "[",
        },
      ],
    },
  ];

  phoneme.value.phone.forEach((item: { score: number; char: string; }) => {
    if (item.score >= 0 && item.score <= 40) {
      soundColor = "rich-text_040";
    } else if (item.score >= 41 && item.score <= 59) {
      soundColor = "rich-text_4159";
    } else if (item.score >= 60 && item.score <= 79) {
      soundColor = "rich-text_6079";
    } else if (item.score >= 80 && item.score <= 100) {
      soundColor = "rich-text_80100";
    }

    childrenNodes.push({
      name: "span",
      attrs: {
        class: soundColor,
      },
      children: [
        {
          type: "text",
          text: item.char,
        },
      ],
    });
  });

  childrenNodes.push({
    name: "span",
    attrs: {
      class: "rich-text_tag",
    },
    children: [
      {
        type: "text",
        text: "]",
      },
    ],
  });

  phonemeNode.value = [{
    name: "div",
    attrs: {
      class: "rich-text_sentence",
    },
    children: childrenNodes,
  }];
}

const handleSetInfoList = (analysisInfo: any) => {
  infoList.value[0].desc = analysisInfo.readMore.length ? analysisInfo.readMore.join() : "无";
  infoList.value[1].desc = analysisInfo.MissedRead.length ? analysisInfo.MissedRead.join() : "无";
  infoList.value[2].desc = analysisInfo.misread.length ? analysisInfo.misread.join() : "无";
  infoList.value[3].desc = analysisInfo.fluency_pause ? `${analysisInfo.fluency_pause}次` : "无";
  infoList.value[4].desc = analysisInfo.fluency_speed ? `${analysisInfo.fluency_speed}词/分钟` : "无";
}

// 基础课音素修复
const handleRepairPhoneme = async (item: any) => {
  return new Promise<void>((resolve, reject) => {
    util.showLoading();

    ossDownLoad(item.user_voice, false).then((oss: { data: any; }) => {
      fs.readFile({
        filePath: oss.data,
        success: (file) => {
          startEvaluating({
            evaluatingInfo: { sentence: item.practice, isPhoneme: true },
            audioBuffer: file.data as ArrayBuffer,
            onSuccess: (eva) => {
              API.skillRepair({
                record_id: item.record_id,
                analysis: JSON.stringify(eva),
              }).then(async res => {
                evaluate.value = res;
                uni.setStorageSync(`${item.record_id}`, JSON.stringify(res));

                util.hideLoading();
                resolve();
              })
            },
            onError: (errMsg) => {
              console.log(errMsg);
              util.showDialogue(errMsg);
              util.hideLoading();

              reject();
            },
          })
        },
        fail: (errMsg) => {
          console.log(errMsg);
          util.hideLoading();
          reject();
        }
      })
    })
  })
}

const handleSetStandardWord = (word: { phone_str: string; char: string; phone: any[] }) => {
  standardWord.value.sound = word.phone_str;
  standardWord.value.word = word.char;
  userWord.value.word = word.char;

  let soundColor = "";
  let childrenNodes: any[] = [
    {
      name: "span",
      attrs: {
        class: "rich-text_tag",
      },
      children: [
        {
          type: "text",
          text: "[",
        },
      ],
    },
  ];
  word.phone.forEach((item) => {
    if (item.score >= 0 && item.score <= 40) {
      soundColor = "rich-text_040";
    } else if (item.score >= 41 && item.score <= 59) {
      soundColor = "rich-text_4159";
    } else if (item.score >= 60 && item.score <= 79) {
      soundColor = "rich-text_6079";
    } else if (item.score >= 80 && item.score <= 100) {
      soundColor = "rich-text_80100";
    }

    childrenNodes.push({
      name: "span",
      attrs: {
        class: soundColor,
      },
      children: [
        {
          type: "text",
          text: item.char,
        },
      ],
    });
  });

  childrenNodes.push({
    name: "span",
    attrs: {
      class: "rich-text_tag",
    },
    children: [
      {
        type: "text",
        text: "]",
      },
    ],
  });

  userWord.value.sound = [
    {
      name: "div",
      attrs: {
        class: "rich-text_sentence",
      },
      children: childrenNodes,
    },
  ] as any;
};

const handlePopUp = async () => {
  if (!(Array.isArray(evaluate.value.analysis.phoneme) && evaluate.value.analysis.phoneme.length)) {
    await handleRepairPhoneme(evaluate.value);
  }

  const phoneme = evaluate.value.analysis.phoneme;
  if (!phoneme || !phoneme.length) {
    return;
  }

  handleSetStandardWord(phoneme[0]);

  showPopup.value = true;
  popupRef.value?.open("bottom");
};

const handleClosePopup = () => {
  showPopup.value = false;
  popupRef.value?.close();
};

const handleActiveWord = (item: any, index: number) => {
  if (item.type === 2) {
    return;
  }
  activeIndex.value = index;

  const phoneme = evaluate.value.analysis.phoneme;
  const curWord = phoneme.find((val: { char: string }) => val.char.toLocaleLowerCase() === item.lab.toLocaleLowerCase());
  handleSetStandardWord(curWord);
};
</script>

<style scoped lang="scss">
@import "./common.scss";

.page-content {
  overflow: hidden;

  .evaluate-container {
    height: 100%;
    overflow-y: auto;
  }
}
</style>